using System;
using BSpec;
using BSpec.Conventions;
using BSpec.Specs;
using NUnit.Framework;

namespace naming_convention_specs
{
    namespace with_scenario_of
    {
        public abstract class matching_a_naming_convention : SpecificationBase<NamingConvention>
        {
            protected override void setup_scenario()
            {
            }

            protected override NamingConvention create_subject()
            {
                return new DefaultNamingConvention();
            }
        }
    }

    namespace given_a_test_fixture_type
    {
        namespace and_the_root_namespace_is_suffixed_with_specs
        {
            [TestFixture]
            public class when_matching_concern : with_scenario_of.matching_a_naming_convention
            {
                protected override void execute_scenario()
                {
                    with_scenario_result(() =>
                        typeof(lower_case_test_fixture_specs.when_test_fixture_has_lower_case)
                        .GetName(NamingConvention.Concern));
                }

                [Test]
                public void should_match_concern()
                {
                    the_scenario_result<string>().should_equal("Lower case test fixture");
                }
            }
        }

        namespace and_the_root_namespace_is_suffixed_with_spec
        {
            [TestFixture]
            public class when_matching_concern : with_scenario_of.matching_a_naming_convention
            {
                protected override void execute_scenario()
                {
                    with_scenario_result(() =>
                        typeof(lower_case_test_fixture_spec.when_test_fixture_has_lower_case)
                        .GetName(NamingConvention.Concern));
                }

                [Test]
                public void should_match_concern()
                {
                    the_scenario_result<string>().should_equal("Lower case test fixture");
                }
            }
        }

        namespace and_the_root_namespace_is_suffixed_with_tests
        {
            [TestFixture]
            public class when_matching_lower_case_concerns_suffixed_with_tests : with_scenario_of.matching_a_naming_convention
            {
                protected override void execute_scenario()
                {
                    with_scenario_result(() =>
                        typeof(lower_case_test_fixture_tests.when_test_fixture_has_lower_case)
                        .GetName(NamingConvention.Concern));
                }

                [Test]
                public void should_match_concern()
                {
                    the_scenario_result<string>().should_equal("Lower case test fixture");
                }
            }
        }

        namespace and_the_root_namespace_is_suffixed_with_test
        {
            [TestFixture]
            public class when_matching_concern : with_scenario_of.matching_a_naming_convention
            {
                protected override void execute_scenario()
                {
                    with_scenario_result(() =>
                        typeof(lower_case_test_fixture_test.when_test_fixture_has_lower_case)
                        .GetName(NamingConvention.Concern));
                }

                [Test]
                public void should_match_concern()
                {
                    the_scenario_result<string>().should_equal("Lower case test fixture");
                }
            }
        }

        namespace and_the_test_fixture_inherits_from_a_base_class_prefixed__with_scenario_of__
        {
            [TestFixture]
            public class when_matching_scenario : with_scenario_of.matching_a_naming_convention
            {
                protected override void execute_scenario()
                {
                    with_scenario_result(() =>
                        typeof(test_fixtures_with_scenarios_specs.when_test_fixture_has_scenario)
                        .BaseType
                        .GetName(NamingConvention.Scenario));
                }

                [Test]
                public void should_match_scenario()
                {
                    the_scenario_result<string>().should_equal("Test fixture with scenarios");
                }
            }
        }

        namespace and_the_test_fixture_inherits_from_a_base_class_prefixed_with__when__
        {
            [TestFixture]
            public class when_matching_scenario : with_scenario_of.matching_a_naming_convention
            {
                protected override void execute_scenario()
                {
                    with_scenario_result(() =>
                        typeof(test_fixtures_with_scenarios_specs.WhenTestFixtureHasScenario)
                        .BaseType
                        .GetName(NamingConvention.Scenario));
                }

                [Test]
                public void should_match_scenario()
                {
                    the_scenario_result<string>().should_equal("Test fixture with scenario");
                }
            }
        }

        namespace and_the_test_fixture_is_camel_case
        {
            [TestFixture]
            public class when_matching_behaviour : with_scenario_of.matching_a_naming_convention
            {
                protected override void execute_scenario()
                {
                    with_scenario_result(() =>
                        typeof(CamelCaseTestFixtureTests.WhenTestFixtureHasCamelCase)
                        .GetName(NamingConvention.Behaviour));
                }

                [Test]
                public void should_convert_to_lower_case()
                {
                    the_scenario_result<string>().should_equal("When test fixture has camel case");
                }
            }
        }

        namespace and_is_camel_case_with_underscores
        {
            [TestFixture]
            public class when_matching_behavior : with_scenario_of.matching_a_naming_convention
            {
                protected override void execute_scenario()
                {
                    with_scenario_result(() =>
                        typeof(CamelCaseTestFixtureTests.When_TestFixture_Has_CamelCase_With_Underscores)
                        .GetName(NamingConvention.Behaviour));
                }

                [Test]
                public void should_convert_to_lower_case()
                {
                    the_scenario_result<string>().should_equal("When test fixture has camel case with underscores");
                }
            }
        }

        namespace and_contains_double_underscores
        {
            [TestFixture]
            public class when_matching_behavior : with_scenario_of.matching_a_naming_convention
            {
                protected override void execute_scenario()
                {
                    with_scenario_result(() =>
                        typeof(test_fixtures_with_scenarios_specs.when_test_fixture_has__double_underscores__)
                        .GetName(NamingConvention.Behaviour));
                }

                [Test]
                public void should_convert_double_underscores_to_quotes()
                {
                    the_scenario_result<string>().should_equal("When test fixture has \"double underscores\"");
                }
            }
        }
    }
}